feat(): SMX-242 - migrate to ESLint 9 flat config#242
feat(): SMX-242 - migrate to ESLint 9 flat config#242danielochoa-epam wants to merge 1 commit intomainfrom
Conversation
81354db to
215c667
Compare
There was a problem hiding this comment.
Pull request overview
Migrates the repo’s linting setup from ESLint 8 legacy config to ESLint 9 flat config, and applies formatting updates across the codebase to align with the new lint/prettier setup.
Changes:
- Added
eslint.config.mjs(flat config) andprettier.config.js; removed legacy.eslintrc.json. - Updated
package.jsonlint script and ESLint/TS/Prettier-related devDependencies. - Applied widespread formatting-only changes across pages, API routes, components, types, and tests.
Reviewed changes
Copilot reviewed 36 out of 48 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| types/order.ts | Formatting-only updates to interface indentation. |
| types/error.ts | Formatting-only, but touches ErrorMessageProps typing. |
| types/db.ts | Formatting-only updates to interface indentation. |
| types/data.ts | Formatting-only updates to interface indentation. |
| types/auth.ts | Formatting-only updates to interface indentation. |
| test/utils.tsx | Reformats provider wrapper + removes eslint-disable comments. |
| test/pages/products/index.spec.tsx | Formatting-only (quotes/indentation). |
| test/pages/products/[pid].spec.tsx | Formatting-only (quotes/indentation). |
| test/pages/productAppExtension/index.spec.tsx | Formatting-only (quotes/indentation). |
| test/pages/index.spec.tsx | Formatting-only (indentation). |
| test/mocks/hooks.ts | Formatting-only (indentation/arrow bodies). |
| prettier.config.js | Adds Prettier configuration used by formatting/lint integration. |
| pages/products/index.tsx | Formatting + small structural changes to early returns (more explicit blocks). |
| pages/products/[pid].tsx | Formatting + minor refactor of early returns / variable style. |
| pages/productAppExtension/[productId]/index.tsx | Formatting + early return blocks for loading/error. |
| pages/orders/[orderId]/modal.tsx | Formatting + early return blocks for loading/error. |
| pages/orders/[orderId]/index.tsx | Formatting + semicolons/early return blocks. |
| pages/index.tsx | Formatting + early return blocks for loading/error. |
| pages/api/uninstall.ts | Formatting-only. |
| pages/api/removeUser.ts | Formatting-only. |
| pages/api/products/list.ts | Formatting + slightly clearer URLSearchParams construction. |
| pages/api/products/index.ts | Formatting-only. |
| pages/api/products/[pid].ts | Formatting + clearer switch/case layout. |
| pages/api/orders/[orderId]/shipping_products.ts | Formatting + signature wrapping for readability. |
| pages/api/orders/[orderId]/index.ts | Formatting-only. |
| pages/api/logout.ts | Formatting-only. |
| pages/api/load.ts | Formatting + minor refactor of helper function formatting. |
| pages/api/auth.ts | Formatting-only. |
| pages/_document.tsx | Formatting-only (bracket/semicolon placement). |
| pages/_app.tsx | Formatting-only (component as concise arrow return). |
| package.json.fe454-backup | Added backup file (non-functional artifact). |
| package.json.backup | Added backup file (non-functional artifact). |
| package.json | Updates lint script and devDependencies for ESLint 9 + plugins. |
| next-env.d.ts | Updates Next.js doc link comment. |
| lib/hooks.ts | Formatting + minor refactors in line breaks/arrow functions. |
| lib/dbs/mysql.ts | Formatting-only. |
| lib/dbs/firebase.ts | Formatting-only. |
| lib/db.ts | Formatting-only. |
| lib/auth.ts | Formatting-only. |
| eslint.config.mjs | Adds ESLint 9 flat config (core of the migration). |
| context/session.tsx | Formatting-only. |
| components/loading.tsx | Formatting-only. |
| components/innerHeader.tsx | Formatting-only. |
| components/header.tsx | Formatting-only (arrays/indentation). |
| components/form.tsx | Formatting-only (imports/layout). |
| components/error.tsx | Formatting-only (but still depends on error.message). |
| .eslintrc.json | Removes legacy ESLint config in favor of flat config. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -43,17 +45,30 @@ | |||
| "@types/react": "^18.2.0", | |||
| "@types/react-dom": "^18.2.1", | |||
| "@types/styled-components": "^5.1.26", | |||
| "@typescript-eslint/eslint-plugin": "^5.30.0", | |||
| "@typescript-eslint/parser": "^5.30.0", | |||
| "@typescript-eslint/eslint-plugin": "^8.26.0", | |||
| "@typescript-eslint/parser": "^8.26.0", | |||
| "babel-jest": "^27.5.1", | |||
| "babel-plugin-styled-components": "^2.0.7", | |||
| "eslint": "^8.19.0", | |||
| "eslint-import-resolver-typescript": "^3.2.5", | |||
| "eslint-plugin-import": "^2.26.0", | |||
| "eslint-plugin-react": "^7.30.1", | |||
| "eslint-plugin-react-hooks": "^4.6.0", | |||
| "eslint": "^9.39.2", | |||
| "eslint-config-prettier": "^10.1.8", | |||
| "eslint-import-resolver-typescript": "^3.10.1", | |||
| "eslint-plugin-gettext": "^1.2.0", | |||
There was a problem hiding this comment.
PR description mentions updating @bigcommerce/eslint-config to v3.x, but this dependency/config isn’t present in package.json or referenced from eslint.config.mjs. Either add/use it as intended, or update the PR description to match the actual approach (custom flat config with individual plugins).
| @@ -43,17 +45,30 @@ | |||
| "@types/react": "^18.2.0", | |||
| "@types/react-dom": "^18.2.1", | |||
| "@types/styled-components": "^5.1.26", | |||
| "@typescript-eslint/eslint-plugin": "^5.30.0", | |||
| "@typescript-eslint/parser": "^5.30.0", | |||
| "@typescript-eslint/eslint-plugin": "^8.26.0", | |||
| "@typescript-eslint/parser": "^8.26.0", | |||
| "babel-jest": "^27.5.1", | |||
| "babel-plugin-styled-components": "^2.0.7", | |||
| "eslint": "^8.19.0", | |||
| "eslint-import-resolver-typescript": "^3.2.5", | |||
| "eslint-plugin-import": "^2.26.0", | |||
| "eslint-plugin-react": "^7.30.1", | |||
| "eslint-plugin-react-hooks": "^4.6.0", | |||
| "eslint": "^9.39.2", | |||
| "eslint-config-prettier": "^10.1.8", | |||
| "eslint-import-resolver-typescript": "^3.10.1", | |||
| "eslint-plugin-gettext": "^1.2.0", | |||
| "eslint-plugin-import": "^2.31.0", | |||
| "eslint-plugin-jest": "^29.12.1", | |||
| "eslint-plugin-jest-dom": "^5.5.0", | |||
| "eslint-plugin-jest-formatting": "^3.1.0", | |||
| "eslint-plugin-jsdoc": "^62.3.1", | |||
| "eslint-plugin-jsx-a11y": "^6.10.2", | |||
| "eslint-plugin-prettier": "^5.5.5", | |||
| "eslint-plugin-react": "^7.37.4", | |||
| "eslint-plugin-react-hooks": "^5.2.0", | |||
| "eslint-plugin-switch-case": "^3.0.1", | |||
| "eslint-plugin-testing-library": "^7.15.4", | |||
| "globals": "^17.0.0", | |||
| "jest": "^28.1.2", | |||
| "jest-environment-jsdom": "^28.1.2", | |||
| "prettier": "^3.8.1", | |||
| "tsutils": "^3.21.0", | |||
| "typescript": "^4.7.3" | |||
There was a problem hiding this comment.
Several new ESLint-related devDependencies appear unused by eslint.config.mjs (e.g., eslint-plugin-jest, eslint-plugin-jsdoc, eslint-plugin-jsx-a11y, eslint-plugin-testing-library, @stylistic/eslint-plugin, etc.). If they’re not part of the intended config, consider removing them to keep the dependency set minimal and reduce install/CI time.
| { | ||
| "name": "sample-app-nodejs", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "dev": "next", | ||
| "build": "next build", | ||
| "start": "next start -p $PORT", | ||
| "test": "jest --updateSnapshot", | ||
| "lint": "eslint . --ext .ts,.tsx,.js", | ||
| "db:setup": "node scripts/db.js" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "engines": { | ||
| "node": ">=18 <20", | ||
| "npm": ">=8 <10" | ||
| }, | ||
| "packageManager": "npm@8.19.4", | ||
| "dependencies": { | ||
| "@bigcommerce/big-design": "^0.36.2", | ||
| "@bigcommerce/big-design-icons": "^0.23.1", | ||
| "@bigcommerce/big-design-theme": "^0.19.1", | ||
| "dotenv": "^16.3.0", | ||
| "firebase-admin": "^13.3.0", | ||
| "jsonwebtoken": "^9.0.1", | ||
| "mysql2": "^3.9.4", | ||
| "next": "^14.2.35", | ||
| "node-bigcommerce": "github:bigcommerce/node-bigcommerce", | ||
| "react": "^18.2.0", | ||
| "react-dom": "^18.2.0", | ||
| "styled-components": "^5.3.11", | ||
| "swr": "^1.3.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@testing-library/dom": "^7.31.2", | ||
| "@testing-library/jest-dom": "^5.16.4", | ||
| "@testing-library/react": "^13.0.0", | ||
| "@types/jest": "^27.5.2", | ||
| "@types/node": "^18.0.0", | ||
| "@types/react": "^18.2.0", | ||
| "@types/react-dom": "^18.2.1", | ||
| "@types/styled-components": "^5.1.26", | ||
| "@typescript-eslint/eslint-plugin": "^5.30.0", | ||
| "@typescript-eslint/parser": "^5.30.0", | ||
| "babel-jest": "^27.5.1", | ||
| "babel-plugin-styled-components": "^2.0.7", | ||
| "eslint": "^8.19.0", | ||
| "eslint-import-resolver-typescript": "^3.2.5", | ||
| "eslint-plugin-import": "^2.26.0", | ||
| "eslint-plugin-react": "^7.30.1", | ||
| "eslint-plugin-react-hooks": "^4.6.0", | ||
| "jest": "^28.1.2", | ||
| "jest-environment-jsdom": "^28.1.2", | ||
| "typescript": "^4.7.3" | ||
| } | ||
| } |
There was a problem hiding this comment.
This appears to be an accidental backup file. It’s not referenced by tooling and will be picked up by packaging/vulnerability scans unnecessarily. Consider removing it from the repo (or adding it to .gitignore if it must exist locally).
| { | |
| "name": "sample-app-nodejs", | |
| "version": "1.0.0", | |
| "description": "", | |
| "main": "index.js", | |
| "scripts": { | |
| "dev": "next", | |
| "build": "next build", | |
| "start": "next start -p $PORT", | |
| "test": "jest --updateSnapshot", | |
| "lint": "eslint . --ext .ts,.tsx,.js", | |
| "db:setup": "node scripts/db.js" | |
| }, | |
| "keywords": [], | |
| "author": "", | |
| "license": "ISC", | |
| "engines": { | |
| "node": ">=18 <20", | |
| "npm": ">=8 <10" | |
| }, | |
| "packageManager": "npm@8.19.4", | |
| "dependencies": { | |
| "@bigcommerce/big-design": "^0.36.2", | |
| "@bigcommerce/big-design-icons": "^0.23.1", | |
| "@bigcommerce/big-design-theme": "^0.19.1", | |
| "dotenv": "^16.3.0", | |
| "firebase-admin": "^13.3.0", | |
| "jsonwebtoken": "^9.0.1", | |
| "mysql2": "^3.9.4", | |
| "next": "^14.2.35", | |
| "node-bigcommerce": "github:bigcommerce/node-bigcommerce", | |
| "react": "^18.2.0", | |
| "react-dom": "^18.2.0", | |
| "styled-components": "^5.3.11", | |
| "swr": "^1.3.0" | |
| }, | |
| "devDependencies": { | |
| "@testing-library/dom": "^7.31.2", | |
| "@testing-library/jest-dom": "^5.16.4", | |
| "@testing-library/react": "^13.0.0", | |
| "@types/jest": "^27.5.2", | |
| "@types/node": "^18.0.0", | |
| "@types/react": "^18.2.0", | |
| "@types/react-dom": "^18.2.1", | |
| "@types/styled-components": "^5.1.26", | |
| "@typescript-eslint/eslint-plugin": "^5.30.0", | |
| "@typescript-eslint/parser": "^5.30.0", | |
| "babel-jest": "^27.5.1", | |
| "babel-plugin-styled-components": "^2.0.7", | |
| "eslint": "^8.19.0", | |
| "eslint-import-resolver-typescript": "^3.2.5", | |
| "eslint-plugin-import": "^2.26.0", | |
| "eslint-plugin-react": "^7.30.1", | |
| "eslint-plugin-react-hooks": "^4.6.0", | |
| "jest": "^28.1.2", | |
| "jest-environment-jsdom": "^28.1.2", | |
| "typescript": "^4.7.3" | |
| } | |
| } | |
| This file was previously a backup copy of package.json. | |
| It has been intentionally cleared so it is not treated as an active package manifest | |
| by build tools or vulnerability scanners. | |
| If you need a backup of package.json, please regenerate it locally instead of | |
| committing it to version control. |
| { | ||
| "name": "sample-app-nodejs", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "dev": "next", | ||
| "build": "next build", | ||
| "start": "next start -p $PORT", | ||
| "test": "jest --updateSnapshot", | ||
| "lint": "eslint . --ext .ts,.tsx,.js", | ||
| "db:setup": "node scripts/db.js" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "engines": { | ||
| "node": ">=18 <20", | ||
| "npm": ">=8 <10" | ||
| }, | ||
| "packageManager": "npm@8.19.4", | ||
| "dependencies": { | ||
| "@bigcommerce/big-design": "^0.36.2", | ||
| "@bigcommerce/big-design-icons": "^0.23.1", | ||
| "@bigcommerce/big-design-theme": "^0.19.1", | ||
| "dotenv": "^16.3.0", | ||
| "firebase-admin": "^13.3.0", | ||
| "jsonwebtoken": "^9.0.1", | ||
| "mysql2": "^3.9.4", | ||
| "next": "^14.2.35", | ||
| "node-bigcommerce": "github:bigcommerce/node-bigcommerce", | ||
| "react": "^18.2.0", | ||
| "react-dom": "^18.2.0", | ||
| "styled-components": "^5.3.11", | ||
| "swr": "^1.3.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@testing-library/dom": "^7.31.2", | ||
| "@testing-library/jest-dom": "^5.16.4", | ||
| "@testing-library/react": "^13.0.0", | ||
| "@types/jest": "^27.5.2", | ||
| "@types/node": "^18.0.0", | ||
| "@types/react": "^18.2.0", | ||
| "@types/react-dom": "^18.2.1", | ||
| "@types/styled-components": "^5.1.26", | ||
| "@typescript-eslint/eslint-plugin": "^5.30.0", | ||
| "@typescript-eslint/parser": "^5.30.0", | ||
| "babel-jest": "^27.5.1", | ||
| "babel-plugin-styled-components": "^2.0.7", | ||
| "eslint": "^8.19.0", | ||
| "eslint-import-resolver-typescript": "^3.2.5", | ||
| "eslint-plugin-import": "^2.26.0", | ||
| "eslint-plugin-react": "^7.30.1", | ||
| "eslint-plugin-react-hooks": "^4.6.0", | ||
| "jest": "^28.1.2", | ||
| "jest-environment-jsdom": "^28.1.2", | ||
| "typescript": "^4.7.3" | ||
| } | ||
| } |
There was a problem hiding this comment.
This appears to be an accidental backup file. It’s not referenced by tooling and will be picked up by packaging/vulnerability scans unnecessarily. Consider removing it from the repo (or adding it to .gitignore if it must exist locally).
| { | |
| "name": "sample-app-nodejs", | |
| "version": "1.0.0", | |
| "description": "", | |
| "main": "index.js", | |
| "scripts": { | |
| "dev": "next", | |
| "build": "next build", | |
| "start": "next start -p $PORT", | |
| "test": "jest --updateSnapshot", | |
| "lint": "eslint . --ext .ts,.tsx,.js", | |
| "db:setup": "node scripts/db.js" | |
| }, | |
| "keywords": [], | |
| "author": "", | |
| "license": "ISC", | |
| "engines": { | |
| "node": ">=18 <20", | |
| "npm": ">=8 <10" | |
| }, | |
| "packageManager": "npm@8.19.4", | |
| "dependencies": { | |
| "@bigcommerce/big-design": "^0.36.2", | |
| "@bigcommerce/big-design-icons": "^0.23.1", | |
| "@bigcommerce/big-design-theme": "^0.19.1", | |
| "dotenv": "^16.3.0", | |
| "firebase-admin": "^13.3.0", | |
| "jsonwebtoken": "^9.0.1", | |
| "mysql2": "^3.9.4", | |
| "next": "^14.2.35", | |
| "node-bigcommerce": "github:bigcommerce/node-bigcommerce", | |
| "react": "^18.2.0", | |
| "react-dom": "^18.2.0", | |
| "styled-components": "^5.3.11", | |
| "swr": "^1.3.0" | |
| }, | |
| "devDependencies": { | |
| "@testing-library/dom": "^7.31.2", | |
| "@testing-library/jest-dom": "^5.16.4", | |
| "@testing-library/react": "^13.0.0", | |
| "@types/jest": "^27.5.2", | |
| "@types/node": "^18.0.0", | |
| "@types/react": "^18.2.0", | |
| "@types/react-dom": "^18.2.1", | |
| "@types/styled-components": "^5.1.26", | |
| "@typescript-eslint/eslint-plugin": "^5.30.0", | |
| "@typescript-eslint/parser": "^5.30.0", | |
| "babel-jest": "^27.5.1", | |
| "babel-plugin-styled-components": "^2.0.7", | |
| "eslint": "^8.19.0", | |
| "eslint-import-resolver-typescript": "^3.2.5", | |
| "eslint-plugin-import": "^2.26.0", | |
| "eslint-plugin-react": "^7.30.1", | |
| "eslint-plugin-react-hooks": "^4.6.0", | |
| "jest": "^28.1.2", | |
| "jest-environment-jsdom": "^28.1.2", | |
| "typescript": "^4.7.3" | |
| } | |
| } | |
| {} |
| export interface ErrorMessageProps { | ||
| error?: ErrorProps; | ||
| renderPanel?: boolean; | ||
| error?: ErrorProps; | ||
| renderPanel?: boolean; |
There was a problem hiding this comment.
ErrorMessageProps.error is typed as optional, but components/error.tsx unconditionally reads error.message. This makes it easy for future callers to pass undefined without a type error and cause a runtime crash. Make error required in the type (or update the component to handle an отсутств error safely).
| // Base JS config | ||
| js.configs.recommended, | ||
| // Prettier config | ||
| prettierConfig, | ||
| // TypeScript/React files | ||
| { | ||
| files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], | ||
| languageOptions: { | ||
| parser: tsParser, | ||
| parserOptions: { | ||
| ecmaVersion: 'latest', | ||
| sourceType: 'module', | ||
| ecmaFeatures: { | ||
| jsx: true, | ||
| }, | ||
| project: './tsconfig.json', | ||
| tsconfigRootDir: import.meta.dirname, | ||
| }, | ||
| globals: { | ||
| ...globals.browser, | ||
| ...globals.node, | ||
| ...globals.es2021, | ||
| React: 'writable', | ||
| }, | ||
| }, | ||
| plugins: { | ||
| '@typescript-eslint': tseslint, | ||
| 'react': reactPlugin, | ||
| 'react-hooks': reactHooksPlugin, | ||
| 'prettier': prettierPlugin, | ||
| }, | ||
| settings: { | ||
| react: { | ||
| version: 'detect', | ||
| }, | ||
| }, | ||
| rules: { | ||
| // Turn off rules TypeScript handles | ||
| 'no-undef': 'off', | ||
| 'no-unused-vars': 'off', | ||
| 'no-redeclare': 'off', | ||
| // Prettier | ||
| 'prettier/prettier': 'warn', | ||
| // TypeScript rules | ||
| '@typescript-eslint/explicit-function-return-type': 'off', | ||
| '@typescript-eslint/no-explicit-any': 'off', | ||
| '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true, argsIgnorePattern: '^_' }], | ||
| '@typescript-eslint/no-use-before-define': 'off', | ||
| '@typescript-eslint/explicit-module-boundary-types': 'off', | ||
| // General rules | ||
| 'no-console': ['error', { allow: ['warn', 'error'] }], | ||
| // React rules | ||
| 'react/display-name': 'off', | ||
| 'react/prop-types': 'off', | ||
| 'react/react-in-jsx-scope': 'off', | ||
| 'react-hooks/rules-of-hooks': 'error', | ||
| 'react-hooks/exhaustive-deps': 'warn', | ||
| }, |
There was a problem hiding this comment.
Compared to the removed legacy .eslintrc.json, this flat config doesn’t apply equivalents of plugin:react/recommended, plugin:react-hooks/recommended, or the import/order/sort-imports rules (even though eslint-plugin-import is installed). If the goal is a pure migration, consider adding the corresponding recommended configs/rules so lint coverage doesn’t regress unintentionally.
| project: './tsconfig.json', | ||
| tsconfigRootDir: import.meta.dirname, | ||
| }, |
There was a problem hiding this comment.
tsconfigRootDir: import.meta.dirname is not supported in the Node.js versions allowed by this repo (package.json engines is ">=18 <20"), which will make ESLint fail to load the flat config. Use a Node 18-compatible alternative (e.g., derive the directory from import.meta.url via fileURLToPath/path.dirname).
| "start": "next start -p $PORT", | ||
| "test": "jest --updateSnapshot", | ||
| "lint": "eslint . --ext .ts,.tsx,.js", | ||
| "lint": "eslint .", |
There was a problem hiding this comment.
The new lint script runs eslint . without --ext/a glob. When ESLint is pointed at a directory, it commonly only lints default JS extensions, which can result in TS/TSX files not being linted. Consider restoring explicit extensions (or using a glob like **/*.{js,jsx,ts,tsx}) so npm run lint still covers the TypeScript codebase.
| "lint": "eslint .", | |
| "lint": "eslint . --ext .js,.jsx,.ts,.tsx", |
What?
This PR migrates the repository from ESLint 8 with legacy configuration to ESLint 9 with flat configuration (
eslint.config.mjs).Changes Made:
eslint.config.mjsflat configuration file@bigcommerce/eslint-configto v3.x with ESLint 9 supportWhy?
ESLint 9 introduces a new flat configuration format that is more flexible and explicit. This migration ensures the repository stays up to date with the latest ESLint tooling and receives security updates.
Testing / Proof
npm run lintpasses locallyRelated: ESLint 9 Migration ADR
@bigcommerce/api-client-developers